import tkinter as tk
from tkinter import filedialog
import os  # 添加 os 模块导入
from attendance_utils import AttendanceUtils, COLUMN_MAPPING
from datetime import datetime, timedelta  # 从 datetime 模块导入 datetime 和 timedelta 类
from chinese_calendar import is_workday, is_holiday
import ttkbootstrap as ttk  # 导入 ttkbootstrap

def validate_input(entry: tk.Entry, dtype: type, error_msg: str, output_text: tk.Text) -> int | float | None:
    """验证输入框的值是否为指定类型"""
    try:
        return dtype(entry.get())
    except ValueError:
        output_text.insert(tk.END, error_msg)
        return None

def validate_file_path(file_path: str, file_type: str, output_text: tk.Text) -> bool:
    """验证文件路径是否有效"""
    if not file_path:
        output_text.insert(tk.END, f"请选择 {file_type} 文件。\n")
        return False
    try:
        AttendanceUtils.ensure_file_exists(file_path)
        return True
    except FileNotFoundError as e:
        output_text.insert(tk.END, f"{file_type} 文件不存在: {e}\n")
        return False
def getMonth():
    """获取上个月的年月，格式为 YYYY-MM"""
    now = datetime.now()  # 直接使用 datetime 类
    first_day_of_last_month = now.replace(day=1) - timedelta(days=1)
    return first_day_of_last_month.strftime("%Y年%m月")
def get_last_month_workdays():
    """
    计算扣除法定节假日后的上个月工作日总数
    :return: 扣除法定节假日后的上个月工作日总数
    """
    # 获取当前日期
    now = datetime.now()
    # 获取上个月的最后一天
    first_day_of_this_month = now.replace(day=1)
    last_day_of_last_month = first_day_of_this_month - timedelta(days=1)
    # 获取上个月的第一天
    first_day_of_last_month = last_day_of_last_month.replace(day=1)
    # 初始化工作日计数器
    workdays = 0
    # 遍历上个月的每一天
    current_day = first_day_of_last_month
    while current_day <= last_day_of_last_month:
        # 判断是否为工作日（排除法定节假日）
        if is_workday(current_day):
            workdays += 1
        # 移动到下一天
        current_day += timedelta(days=1)
    return workdays

class AttendanceDataProcessor:
    def __init__(self, root: ttk.Window):  # 使用 ttk.Window
        self.root = root
        self.root.title("考勤数据处理工具")
        self.root.style.theme_use('litera')  # 使用 Windows 11 风格的主题
        self.font_style = ("Arial", 10)
        # 初始化输入框变量
        self.work_month_entry = None
        self.work_days_entry = None
        self.src_file_entry = None
        self.report_file_entry = None
        self.list_file_entry = None
        self.row_index = 0  # 新增一个行索引变量
        self.create_input_fields()
        self.create_buttons_and_output()

    def create_input_fields(self):
        """创建输入字段"""
        self._create_entry("工作月份:", getMonth())
        self._create_entry("本月应工作天数:", get_last_month_workdays())
        self._create_file_entry("月度汇总表文件:", self.browse_src_file)
        self._create_file_entry("考勤统计表文件:", self.browse_report_file)
        self._create_file_entry("花名册文件路径:", self.browse_list_file)

    def _create_entry(self, label_text: str, default_value: str):
        """创建普通输入框"""
        label = tk.Label(self.root, text=label_text, font=self.font_style)
        label.grid(row=self.row_index, column=0, padx=10, pady=5, sticky=tk.W)
        entry = tk.Entry(self.root, font=self.font_style)
        entry.insert(0, default_value)
        entry.grid(row=self.row_index, column=1, padx=10, pady=5, sticky=tk.EW)
        if label_text == "工作月份:":
            self.work_month_entry = entry
        elif label_text == "本月应工作天数:":
            self.work_days_entry = entry
        self.row_index += 1  # 增加行索引

    def _create_file_entry(self, label_text: str, browse_command):
        """创建文件选择输入框"""
        label = tk.Label(self.root, text=label_text, font=self.font_style)
        label.grid(row=self.row_index, column=0, padx=10, pady=5, sticky=tk.W)
        entry = tk.Entry(self.root, width=46, font=self.font_style)
        entry.grid(row=self.row_index, column=1, padx=10, pady=5, sticky=tk.EW)
        button = tk.Button(self.root, text="浏览", width=10, command=browse_command, font=self.font_style)
        button.grid(row=self.row_index, column=2, padx=10, pady=10, sticky=tk.E)
        if label_text == "月度汇总表文件:":
            self.src_file_entry = entry
        elif label_text == "考勤统计表文件:":
            self.report_file_entry = entry
        # 确保 label_text 完全匹配
        elif label_text == "花名册文件路径:":
            self.list_file_entry = entry
        self.row_index += 1  # 增加行索引

    def create_buttons_and_output(self):
        """创建按钮和输出文本框"""
        # 直接指定行号
        button_row = self.row_index
        # 设置按钮列号为 2 以实现右对齐
        run_button = tk.Button(self.root, text="运行脚本", width=10, command=self.run_script, font=self.font_style)
        run_button.grid(row=button_row, column=2, padx=10, pady=5, sticky=tk.E)
        text_row = button_row + 1
        self.output_text = tk.Text(self.root, height=10, width=80, font=self.font_style)
        # 设置文本框列号为 0 并跨 3 列，同时右对齐
        self.output_text.grid(row=text_row, column=0, columnspan=3, padx=10, pady=5, sticky=tk.W)
        # 更新行索引
        self.row_index = text_row + 1

    def run_script(self):
        """运行脚本"""
        work_days = validate_input(self.work_days_entry, int, "本月应工作天数必须为整数，请重新输入。\n", self.output_text)
        if work_days is None:
            return
        work_month = self.work_month_entry.get()
        src_file = self.src_file_entry.get()
        report_file = self.report_file_entry.get()
        list_file = self.list_file_entry.get()

        if not all([
            validate_file_path(src_file, "月度汇总表", self.output_text),
            validate_file_path(report_file, "考勤统计表", self.output_text),
            validate_file_path(list_file, "花名册", self.output_text)
        ]):
            return

        report_folder = os.path.dirname(report_file)
        AttendanceUtils.ensure_folder_exists(report_folder)

        worker_dict = AttendanceUtils.build_worker_dict(list_file)
        data_chunks = AttendanceUtils.process_data_chunks(src_file, worker_dict, work_days, self.output_text)

        AttendanceUtils.write_to_excel(report_file, work_month, data_chunks, COLUMN_MAPPING, work_days, worker_dict)
        self.output_text.insert(tk.END, f"数据已汇总到 {report_file}\n")

    def browse_src_file(self):
        """浏览月度汇总表文件"""
        file_path = filedialog.askopenfilename()
        self.src_file_entry.delete(0, tk.END)
        self.src_file_entry.insert(0, file_path)

    def browse_report_file(self):
        """浏览考勤统计表文件"""
        file_path = filedialog.askopenfilename()
        self.report_file_entry.delete(0, tk.END)
        self.report_file_entry.insert(0, file_path)

    def browse_list_file(self):
        """浏览花名册文件"""
        file_path = filedialog.askopenfilename()
        self.list_file_entry.delete(0, tk.END)
        self.list_file_entry.insert(0, file_path)

if __name__ == "__main__":
    root = ttk.Window(themename='litera')  # 使用 ttk.Window 创建窗口
    app = AttendanceDataProcessor(root)
    root.mainloop()